unit fMeshObjects;

interface

uses
  Winapi.OpenGL,
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs,
  Vcl.StdCtrls,
  Vcl.ExtCtrls,
  Vcl.Imaging.jpeg,

  GLS.VectorLists,
  GLS.Texture,
  GLS.SceneViewer,
  GLS.Scene,
  GLS.VectorTypes,
  GLS.VectorGeometry,
  GLS.VectorFileObjects,
  GLS.File3DS,
  GLS.Objects,
  GLS.GeomObjects,
  GLS.Material,
  GLS.Coordinates,

  GLS.BaseClasses,
  GLS.RenderContextInfo,
  GLS.Cadencer,
  GLS.MeshBuilder,
  GLS.SimpleNavigation;

type
  TForm1 = class(TForm)
    GLScene1: TGLScene;
    MatLib: TGLMaterialLibrary;
    Camera: TGLCamera;
    GLLightSource1: TGLLightSource;
    GLFreeForm: TGLFreeForm;
    Dummy: TGLDummyCube;
    GLCadencer1: TGLCadencer;
    PanelLeft: TPanel;
    GLSceneViewer1: TGLSceneViewer;
    btnCubeMesh: TButton;
    btnCylinderMesh: TButton;
    btnHalfSphere: TButton;
    btnKern: TButton;
    GLSimpleNavigation1: TGLSimpleNavigation;
    Button1: TButton;
    procedure btnCubeMeshClick(Sender: TObject);
    procedure GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState;
      X, Y: Integer);
    procedure GLDirectOpenGL1Render(var rci: TGLRenderContextInfo);
    procedure GLCadencer1Progress(Sender: TObject;
      const DeltaTime, NewTime: Double);
    procedure FormCreate(Sender: TObject);
    procedure btnCylinderMeshClick(Sender: TObject);
    procedure btnHalfSphereClick(Sender: TObject);
    procedure btnKernClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    FileName: TFileName;
    FOldX, FOldY: Integer;
    Position, Scale : TVector3f;
    MeshHexahedronA, MeshHexahedronB, MeshHexahedronC: TGLMeshObject;
    MeshCylinderA, MeshCylinderB, MeshCylinderC: TGLMeshObject;

    Sphere: TGLSphere;
    Kern: TGLCylinder;
    Disk, DiskTop, DiskBot: TGLDisk;
  public

  end;

var
  Form1: TForm1;


//================================================
implementation
//================================================

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  SetCurrentDir(ExtractFilePath(ParamStr(0)));
  FileName := GetCurrentDir() + '\Data\';
  SetCurrentDir(FileName);

  // Create Mesh Objects
  MeshHexahedronA := TGLMeshObject.CreateOwned(GLFreeForm.MeshObjects);
  MeshHexahedronA.Mode := momFaceGroups;
  MeshHexahedronB := TGLMeshObject.CreateOwned(GLFreeForm.MeshObjects);
  MeshHexahedronB.Mode := momFaceGroups;
  MeshHexahedronC := TGLMeshObject.CreateOwned(GLFreeForm.MeshObjects);
  MeshHexahedronC.Mode := momFaceGroups;

  MeshCylinderA := TGLMeshObject.CreateOwned(GLFreeForm.MeshObjects);
  MeshCylinderA.Mode := momFaceGroups;
  MeshCylinderB := TGLMeshObject.CreateOwned(GLFreeForm.MeshObjects);
  MeshCylinderB.Mode := momFaceGroups;
  MeshCylinderC := TGLMeshObject.CreateOwned(GLFreeForm.MeshObjects);
  MeshCylinderC.Mode := momFaceGroups;

//  MeshHexahedronC.Material.Texture.Disabled := False;
//  MeshHexahedronC.Material.Texture.Image.LoadFromFile('walkway.jpg');
end;

procedure TForm1.btnCubeMeshClick(Sender: TObject);
var
  aVec: TAffineVector;
begin
  aVec := AffineVectormake(1.0, 1.0, 1.0);
  Position := AffineVectormake(-1.5,1.5,1.0);
  Scale := VectorScale(aVec,0.5);

  BuildMeshCube(MeshHexahedronB, Position, Scale);
  MakeMeshHexahedron(MeshHexahedronC);
  GLFreeForm.StructureChanged;
  GLSceneViewer1.RecreateWnd;
end;

procedure TForm1.btnCylinderMeshClick(Sender: TObject);
var
  Slices: Integer;
begin
  Slices := 16;
  Scale := VectorScale(AffineVectormake(1.0, 1.0, 1.0),0.5);
  Position := AffineVectorMake(0.5,0.5,0.5);
  BuildMeshCylinder(MeshCylinderB, Position, Scale, Slices);
  Position := AffineVectorMake(-1.5,1.5,1.5);
  BuildMeshCylinderAdv(MeshCylinderA, Position, Scale, 1, 1, 3, Slices);
  GLFreeForm.StructureChanged;
  GLSceneViewer1.RecreateWnd;
end;

//
// HalfSphere := Sphere + 1Disk
//
procedure TForm1.btnHalfSphereClick(Sender: TObject);
begin
  Sphere := TGLSphere.CreateAsChild(Dummy);
  Sphere.Material.Texture.Disabled := False;
  Sphere.Material.Texture.Image.LoadFromFile('earth.jpg');
  Sphere.Position.SetPoint(0.0, -1.5, 0);
  Sphere.Radius := 1.0;
  Sphere.Slices := 32;
  Sphere.Stacks := 32;     // if 2 - two cones
  Sphere.Top := 0;         // top angle

  // Create Disk
  Disk := TGLDisk.CreateAsChild(Dummy);
  Disk.Material.Texture.Disabled := False;
  Disk.Material.Texture.Image.LoadFromFile('moon.jpg');
  Disk.Position.SetPoint(0.0, -1.5, 0);
  Disk.Direction.SetVector(0, 1, 0);
  Disk.OuterRadius := 1.0;
  Disk.Slices := 16;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 // GLSceneViewer1.RemoveComponent(Self);
  GLSceneViewer1.Update;
  GLSceneViewer1.Refresh;
  GLSceneViewer1.Repaint;
  GLSceneViewer1.ResetPerformanceMonitor;
end;

// Kern := Cylinder + 2Disks
//
procedure TForm1.btnKernClick(Sender: TObject);
begin
  // Create  GLCylinder
  Kern := TGLCylinder.CreateAsChild(Dummy);
  Kern.Material.Texture.Disabled := False;
  Kern.Material.Texture.Image.LoadFromFile('earth.jpg');
  Kern.Position.SetPoint(0.0, 2.0, 0);
  Kern.TopRadius := 0.5;
  Kern.BottomRadius := 0.5;
  Kern.Height := 1.0;
  Kern.Parts := [cySides, cyTop, cyBottom];
  Kern.Slices := 32;
  Kern.Stacks := 32;     // if 2 - two cones

  // Create 1Disk for bottom
  DiskBot := TGLDisk.CreateAsChild(Dummy);
  DiskBot.Material.Texture.Disabled := False;
  DiskBot.Material.Texture.Image.LoadFromFile('mars.jpg');
  DiskBot.Position.SetPoint(0.0, 1.49, 0);
  DiskBot.Direction.SetVector(0, -1, 0);
  DiskBot.OuterRadius := 0.5;
  DiskBot.Slices := 16;

  // Create 2Disk for top
  DiskTop := TGLDisk.CreateAsChild(Dummy);
  DiskTop.Material.Texture.Disabled := False;
  DiskTop.Material.Texture.Image.LoadFromFile('mars.jpg');
  DiskTop.Position.SetPoint(0.0, 2.51, 0);
  DiskTop.Direction.SetVector(0, 1, 0);
  DiskTop.OuterRadius := 0.5;
  DiskTop.Slices := 16;

end;


procedure TForm1.GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FOldX := X;
  FOldY := Y;
end;

procedure TForm1.GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
  if ssLeft in Shift then
  begin
    Camera.MoveAroundTarget(FOldY - Y, FOldX - X);
    FOldX := X;
    FOldY := Y;
  end;
end;

procedure TForm1.GLCadencer1Progress(Sender: TObject;
  const DeltaTime, NewTime: Double);
begin
  Camera.Turn(DeltaTime * 20);
end;

procedure TForm1.GLDirectOpenGL1Render(var rci: TGLRenderContextInfo);
begin
  glBegin(GL_QUADS);
  glVertex3f(-1.0, -1.0, 1.0);
  glVertex3f(1.0, -1.0, 1.0);
  glVertex3f(1.0, 1.0, 1.0);
  glVertex3f(-1.0, 1.0, 1.0);
  glEnd();
end;

end.
